package com.weilx959.spt.plugin.e2sp.model.statement;

import com.weilx959.spt.core.utils.Assert;
import com.weilx959.spt.plugin.e2sp.constant.Dialect;
import com.weilx959.spt.plugin.e2sp.constant.SQLType;
import com.weilx959.spt.plugin.e2sp.utils.ResourceBundleUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 抽象语句vo
 *
 * @author weilx
 * @since 2024-05-02
 */
@Data
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class ParentStatement implements Statement {
    /**
     * 数据库方言
     */
    private Dialect dialect;

    /**
     * 工作簿名称
     */
    private String sheetName;

    /**
     * 工作簿索引
     */
    private int sheetIndex;

    /**
     * 行索引
     */
    private int rowIndex;

    /**
     * 数据库名称
     */
    private String schema;

    /**
     * 表名称
     */
    private String tableName;

    /**
     * 主键列表
     */
    private List<String> keys;

    /**
     * 全部列名列表
     */
    private List<String> columns;

    /**
     * 数据值列表
     */
    private List<Object> values;

    /**
     * SQL语句
     */
    private String sql;

    /**
     * 构造函数
     *
     * @param another 另一个ParentStatement对象
     */
    public ParentStatement(ParentStatement another) {
        this.dialect = another.dialect;
        this.sheetName = another.sheetName;
        this.sheetIndex = another.sheetIndex;
        this.rowIndex = another.rowIndex;
        this.schema = another.schema;
        this.tableName = another.tableName;
        this.keys = another.keys;
        this.columns = another.columns;
        this.values = another.values;
        this.sql = another.sql;
    }

    /**
     * 获取主键列名-值映射
     *
     * @return {@link Map}<{@link String}, {@link String}>
     */
    public Map<String, Object> getKeyColumnMap() {
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptyMap();
        }
        Map<String, Object> keyColumnMap = new HashMap<>();

        for (String key : keys) {
            int i = columns.indexOf(key);
            Assert.check(i > -1, String.format(ResourceBundleUtil.get().getString("e2s.submit.message.pk-is-empty"), key));
            keyColumnMap.put(key, values.get(i));
        }
        return keyColumnMap;
    }

    /**
     * 获取列-值映射
     *
     * @return {@link Map}<{@link String}, {@link String}>
     */
    public Map<String, Object> getColumnMap() {
        Assert.check(columns.size() == values.size(), ResourceBundleUtil.get().getString("e2s.submit.message.column-size-not-match-value-size"));

        if (CollectionUtils.isEmpty(columns) && CollectionUtils.isEmpty(values)) {
            return Collections.emptyMap();
        }
        Map<String, Object> columnMap = new HashMap<>();

        for (int i = 0; i < columns.size(); i++) {
            columnMap.put(columns.get(i), values.get(i));
        }
        return columnMap;
    }

    /**
     * 获取列值
     *
     * @param column 列名
     * @return {@link String}
     */
    public Object getColumnValue(String column) {
        int i = columns.indexOf(column);
        Assert.check(i > -1, String.format(ResourceBundleUtil.get().getString("e2s.submit.message.column-not-exist"), column));
        return values.get(i);
    }

    @Override
    public String toString() {
        return this.sql;
    }

    @Override
    public SQLType getType() {
        return null;
    }

    @Override
    public String getSql() {
        return this.sql;
    }

    @Override
    public void setSql(String sql) {
        this.sql = sql;
    }
}
